<template>
  <el-upload
    v-bind="$attrs"
    :multiple="props.multiple"
    :limit="props.limit"
  :on-exceed="handleExceed"
    :http-request="handleUpload"
    :before-upload="beforeUpload"
    :on-remove="handleRemove"
  >
    <slot>
      <el-button type="primary">点击上传</el-button>
    </slot>
    <template #tip>
      <div class="tip-text">
        支持 {{ allowedExtensions.join(", ") }} 文件，不超过 {{ maxSizeMB }}MB
      </div>
    </template>
  </el-upload>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { ElMessage } from "element-plus";
import type { UploadProps } from "element-plus";

interface Props {
  api: (file: File) => Promise<string>; // 上传接口
  allowedExtensions?: string[]; // 允许的文件扩展名
  apiParams?: any;
  multiple?: boolean;
  limit?: number;
  maxSizeMB?: number; // 文件大小限制（MB）
}

const props = withDefaults(defineProps<Props>(), {
  allowedExtensions: () => [".jpg", ".png"],
  maxSizeMB: 5,
});
const fileList= ref([]);
const emit = defineEmits(["success", "error"]);
const handleExceed: UploadProps['onExceed'] = (files) => {
  ElMessage.warning(`最多上传 ${props.limit} 个文件`);
};

// 上传前校验
const beforeUpload: UploadProps["beforeUpload"] = (file) => {
  const ext = file.name.slice(file.name.lastIndexOf(".")).toLowerCase();
  const isSizeValid = file.size / 1024 / 1024 < props.maxSizeMB;
  const isTypeValid = props.allowedExtensions.includes(ext);
  // 数量验证
  const isLimitValid = props.limit ? fileList.value.length < props.limit : true;
   if (!isLimitValid) {
    ElMessage.error(`文件数量不能超过 ${props.limit} 个`);
    return false;
  }
  if (!isTypeValid) {
    ElMessage.error(`仅支持 ${props.allowedExtensions.join(", ")} 格式`);
    return false;
  }
  if (!isSizeValid) {
    ElMessage.error(`文件大小不能超过 ${props.maxSizeMB}MB`);
    return false;
  }
  return true;
};

// 自定义上传
const handleUpload: UploadProps["httpRequest"] = async (options) => {
  try {
    const fileUrl = await props.api(options.file);
    emit("success", fileUrl);
  } catch (error) {
    emit("error", error);
  }
};

// 删除文件
const handleRemove = () => emit("success", "");
</script>
<style lang="scss" scoped>
:deep(.tip-text) {
  color: var(--text-color-primary);
  font-size: 12px;
}
</style>